#include "syntax_parser.h"
#include "errors_warnings.h"

#include "main_container.h"

extern MainContainer * CompilerData;



// <generate_block> ~ generate <upto_expression> <generate_transactions> <after_expression> <every_expression> ;  {generate}
void Parser::Parse_GenerateBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_GenerateBlock");
#endif
		
	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordGenerate )
	{
		// write type of production in this node
		parent->Production = Gr_GenerateBlock__generate_UptoExpression_GenerateTransactions_AfterExpression_EveryExpression_spSemiCol;

		// process terminal symbol 'generate' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <upto_expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_UptoExpression(newNode1);

		// process nonterminal symbol <generate_transactions> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_GenerateTransactions(newNode2);

		// process nonterminal symbol <after_expression> 
		SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode3);
		Parse_AfterExpression(newNode3);

		// process nonterminal symbol <every_expression> 
		SyntaxTreeNode * newNode4 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode4);
		Parse_EveryExpression(newNode4);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon )
		{
			SyntaxTreeNode * newNode5 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode5);
			newNode5->LexUnitID=this->CurrentLexicPosition;
			newNode5->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}

	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_GENERATE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_GenerateBlock");
#endif
}

// <upto_expression> ~ upto <expression>  {upto}
// <upto_expression> ~ ? {NAME, after, every, ;, send}
void Parser::Parse_UptoExpression(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_UptoExpression");
#endif
	LexicUnit currentUnit;

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUpto )
	{
		// write type of production in this node
		parent->Production = Gr_UptoExpression__upto_Expression;

		// process terminal symbol 'upto' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

	}

	else if( ( currentUnit.type == LUTypeIdentifier ) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordAfter ) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEvery ) ||
		( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend ) ||
		( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon ) )
	{
		// write type of production in this node
		parent->Production = Gr_UptoExpression__epsilon;

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_UPTO_EXPRESSION_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_UptoExpression");
#endif
}

// <after_expression> ~ after <expression>  {after}
// <after_expression> ~ ? {every, ;, send}
void Parser::Parse_AfterExpression(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_AfterExpression");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordAfter )
	{
		// write type of production in this node
		parent->Production = Gr_AfterExpression__after_Expression;

		// process terminal symbol 'after' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

	}

	else if( (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEvery) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend) ||
		(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon) )
	{
		// write type of production in this node
		parent->Production = Gr_AfterExpression__epsilon;
	}

	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_AFTER_EXPRESSIO_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_AfterExpression");
#endif
}


// <every_expression> ~ every <expression> <plus_minus_expression>  {every}
// <every_expression> ~ ? {;, send}
void Parser::Parse_EveryExpression(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_EveryExpression");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEvery )
	{
		// write type of production in this node
		parent->Production = Gr_EveryExpression__every_Expression_PlusMinusExpression;

		// process terminal symbol 'every' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

		// process nonterminal symbol <plus_minus_expression> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_PlusMinusExpression(newNode2);

	}

	else if( (currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend) ||
		(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon) )
	{
		// write type of production in this node
		parent->Production = Gr_EveryExpression__epsilon ;
	}
	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_EVERY_EXPRESSION_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_EveryExpression");
#endif
}

// <plus_minus_expression> ~ +- <expression>  {+-}
// <plus_minus_expression> ~ ? {;, send}
void Parser::Parse_PlusMinusExpression(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_PlusMinusExpression");
#endif
	LexicUnit currentUnit;
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterPlusOrMinus )
	{
		// write type of production in this node
		parent->Production = Gr_PlusMinusExpression__spPlusMinus_Expression;

		// process terminal symbol '+-' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

	}

	else if( (currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon) || 
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSend) )
	{
		// write type of production in this node
		parent->Production = Gr_PlusMinusExpression__epsilon;
	}
	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_PLUS_MINUS_EXPRESSION_BEGINING);		// MAKE LOGICAL RECOVERING
		// MAKE LOGICAL RECOVERING
	}

#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_PlusMinusExpression");
#endif
}


// <trans_list> ~ <name> : <expression> <trans_list_adds>  {NAME}
void Parser::Parse_TransList(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_TransList");
#endif

	LexicUnit currentUnit;
	
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeIdentifier )
	{
		// write type of production in this node
		parent->Production = Gr_TransList__Name_spColon_Expression_TransListAdds;

		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Name(newNode0);

		// process terminal symbol ':' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon )
		{
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_COLON_MATCH);
			CurrentLexicPosition++;
		}

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_Expression(newNode2);

		// process nonterminal symbol <trans_list_adds> 
		SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode3);
		Parse_TransListAdds(newNode3);
	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_TRANS_LIST_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
	
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_TransList");
#endif

}
// <trans_list_adds> ~ <trans_list_add> <trans_list_adds>  {;}
// <trans_list_adds> ~ ? {)}
void Parser::Parse_TransListAdds(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_TransListAdds");
#endif

	LexicUnit currentUnit;

	// get current lexic unit
	do
	{
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif	
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon )
		{
			// write type of production in this node
			parent->Production = Gr_TransListAdds__TransListAdd_TransListAdds;

			// process nonterminal symbol <trans_list_add> 
			SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode0);
			Parse_TransListAdd(newNode0);

		}

		else if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterRightParenthesis )
		{
			// write type of production in this node
			parent->Production = Gr_TransListAdds__TransListAdd_TransListAdds;
			break;
		}


		else
		{
			// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_TRANS_LIST_ADDS_BEGINING);			// MAKE LOGICAL RECOVERING
			this->CurrentLexicPosition++;
			break;
		}
	}while(1);
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_TransListAdds");
#endif
}
// <trans_list_add> ~ ; <name> : <expression>  {;}
void Parser::Parse_TransListAdd(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_TransListAdd");
#endif

	LexicUnit currentUnit;
	
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif		
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon )
	{
		// write type of production in this node
		parent->Production = Gr_TransListAdd__spSemiCol_Name_spColon_Expression ;

		// process terminal symbol ';' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Name(newNode1);

		// process terminal symbol ':' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterColon )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_COLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode3);
		Parse_Expression(newNode3);

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_TRANS_LIST_ADD_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_TransListAdd");
#endif
}


// <advance_block> ~ advance <expression> <plus_minus_expression> ;  {advance}
void Parser::Parse_AdvanceBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_AdvanceBlock");
#endif


	LexicUnit currentUnit;
	
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordAdvance )
	{
		// write type of production in this node
		parent->Production = Gr_AdvanceBlock__advance_Expression_PlusMinusExpression_spSemiCol;

		// process terminal symbol 'advance' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

		// process nonterminal symbol <plus_minus_expression> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_PlusMinusExpression(newNode2);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon )
		{
			SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode3);
			newNode3->LexUnitID=this->CurrentLexicPosition;
			newNode3->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ADVANCE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_AdvanceBlock");
#endif
}


// <enter_block> ~ enter <units_in_expression> <expression> <forming_expression> ;  {enter}
void Parser::Parse_EnterBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_EnterBlock");
#endif

	LexicUnit currentUnit;

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordEnter )
	{
		// write type of production in this node
		parent->Production = Gr_EnterBlock__enter_UnitsInExpression_Expression_FormingExpression_spSemiCol;

		// process terminal symbol 'enter' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <units_in_expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_UnitsInExpression(newNode1);

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_Expression(newNode2);

		// process nonterminal symbol <forming_expression> 
		SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode3);
		Parse_FormingExpression(newNode3);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon  )
		{
			SyntaxTreeNode * newNode4 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode4);
			newNode4->LexUnitID=this->CurrentLexicPosition;
			newNode4->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ENTER_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_EnterBlock");
#endif
}


// <forming_expression> ~ forming <expression>  {forming}
// <forming_expression> ~ ? {;, while, until}
void Parser::Parse_FormingExpression(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_FormingExpression");
#endif

	LexicUnit currentUnit;

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordForming )
	{
		// write type of production in this node
		parent->Production = Gr_FormingExpression__forming_Expression;

		// process terminal symbol 'forming' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

	}

	else if( 
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordWhile) ||
		(currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordUntil) ||
		(currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon) )
	{
		// write type of production in this node
		parent->Production = Gr_FormingExpression__epsilon;
	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_FORMING_EXPRESSION_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_FormingExpression");
#endif
}


// <leave_block> ~ leave <units_from_expression> <expression> ;  {leave}
void Parser::Parse_LeaveBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_LeaveBlock");
#endif

	LexicUnit currentUnit;

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordLeave )
	{
		// write type of production in this node
		parent->Production = Gr_LeaveBlock__leave_UnitsFromExpression_Expression_spSemiCol;

		// process terminal symbol 'leave' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <units_from_expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_UnitsFromExpression(newNode1);

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_Expression(newNode2);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon )
		{
			SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode3);
			newNode3->LexUnitID=this->CurrentLexicPosition;
			newNode3->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}
	}

	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LEAVE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}

#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_LeaveBlock");
#endif
}



// <seize_block> ~ seize <expression> <forming_expression> ;  {seize}
void Parser::Parse_SeizeBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_SeizeBlock");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordSeize )
	{
		// write type of production in this node
		parent->Production = Gr_SeizeBlock__seize_Expression_FormingExpression_spSemiCol;

		// process terminal symbol 'seize' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

		// process nonterminal symbol <forming_expression> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_FormingExpression(newNode2);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon )
		{
			SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode3);
			newNode3->LexUnitID=this->CurrentLexicPosition;
			newNode3->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}

	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEIZE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_SeizeBlock");
#endif
}


// <release_block> ~ release <expression> ;  {release}
void Parser::Parse_ReleaseBlock(SyntaxTreeNode * parent)
{

#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ReleaseBlock");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordRelease )
	{
		// write type of production in this node
		parent->Production = Gr_ReleaseBlock__release_Expression_spSemiCol;

		// process terminal symbol 'release' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter && currentUnit.subtype == SpecialCharacterSemicolon )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}

	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_RELEASE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ReleaseBlock");
#endif
}


// <inqueue_block> ~ inqueue <expression> ;  {inqueue}
void Parser::Parse_InqueueBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_InqueueBlock");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordInqueue )
	{
		// write type of production in this node
		parent->Production = Gr_InqueueBlock__inqueue_Expression_spSemiCol;

		// process terminal symbol 'inqueue' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterSemicolon  )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_INQUEUE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_InqueueBlock");
#endif
}




// <outqueue_block> ~ outqueue <expression> ;  {outqueue}
void Parser::Parse_OutqueueBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_OutqueueBlock");
#endif
	LexicUnit currentUnit;

#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordOutqueue )
	{
		// write type of production in this node
		parent->Production = Gr_OutqueueBlock__outqueue_Expression_spSemiCol;

		// process terminal symbol 'outqueue' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterSemicolon  )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}

	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_OUTQUEUE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_OutqueueBlock");
#endif
}


// <arrive_block> ~ arrive <expression> ;  {arrive}
void Parser::Parse_ArriveBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ArriveBlock");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordArrive )
	{
		// write type of production in this node
		parent->Production = Gr_ArriveBlock__arrive_Expression_spSemiCol;

		// process terminal symbol 'arrive' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterSemicolon  )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_ARRIVE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ArriveBlock");
#endif
}


// <depart_block> ~ depart <expression> ;  {depart}
void Parser::Parse_DepartBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_DepartBlock");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordDepart )
	{
		// write type of production in this node
		parent->Production = Gr_DepartBlock__depart_Expression_spSemiCol;

		// process terminal symbol 'depart' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <expression> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Expression(newNode1);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterSemicolon  )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_DEPART_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_DepartBlock");
#endif
}


// <model_instance_block> ~ model <name> ( <arguments> );  {model}
// <model_instance_block> ~ <name> ( <arguments> );  {NAME}
void Parser::Parse_ModelInstanceBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_ModelInstanceBlock");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword && currentUnit.subtype == KeywordModel )
	{
		// write type of production in this node
		parent->Production = Gr_ModelInstanceBlock__model_Name_spLPar_Arguments_spRPar_spSemiCol;

		// process terminal symbol 'model' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Name(newNode1);

		// process terminal symbol '(' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if(  currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterLeftParenthesis )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LEFT_PARENTHESIS_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process nonterminal symbol <arguments> 
		SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode3);
		Parse_Arguments(newNode3);

		// process terminal symbol ')' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterRightParenthesis  )
		{
			SyntaxTreeNode * newNode4 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode4);
			newNode4->LexUnitID=this->CurrentLexicPosition;
			newNode4->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error 
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_RIGHT_PARENTHESIS_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterSemicolon  )
		{
			SyntaxTreeNode * newNode5 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode5);
			newNode5->LexUnitID=this->CurrentLexicPosition;
			newNode5->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}

	else if( currentUnit.type == LUTypeIdentifier )
	{
		// write type of production in this node
		parent->Production = Gr_ModelInstanceBlock__Name_spLPar_Arguments_spRPar_spSemiCol;

		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		Parse_Name(newNode0);

		// process terminal symbol '(' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterLeftParenthesis  )
		{
			SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode1);
			newNode1->LexUnitID=this->CurrentLexicPosition;
			newNode1->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_LEFT_PARENTHESIS_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process nonterminal symbol <arguments> 
		SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode2);
		Parse_Arguments(newNode2);

		// process terminal symbol ')' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterRightParenthesis  )
		{
			SyntaxTreeNode * newNode3 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode3);
			newNode3->LexUnitID=this->CurrentLexicPosition;
			newNode3->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_RIGHT_PARENTHESIS_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterSemicolon  )
		{
			SyntaxTreeNode * newNode4 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode4);
			newNode4->LexUnitID=this->CurrentLexicPosition;
			newNode4->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_MODEL_INSTANCE_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_ModelInstanceBlock");
#endif
}


// <goto_block> ~ goto <name> ;  {goto}
void Parser::Parse_GotoBlock(SyntaxTreeNode * parent)
{
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("Parse_GotoBlock");
#endif

	LexicUnit currentUnit;
#ifdef TRACE
	CompilerData->LogTrace->ReportLine("Getting lexic unit.");
#endif
	// get current lexic unit
	currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);

	if( currentUnit.type == LUTypeKeyword  && currentUnit.subtype == KeywordGoto )
	{
		// write type of production in this node
		parent->Production = Gr_GotoBlock__goto_Name_spSemiCol;

		// process terminal symbol 'goto' 
		SyntaxTreeNode * newNode0 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode0);
		newNode0->LexUnitID=this->CurrentLexicPosition;
		newNode0->Production=Gr_Terminal;
		//increase counter
		CurrentLexicPosition++;

		// process nonterminal symbol <name> 
		SyntaxTreeNode * newNode1 = new SyntaxTreeNode();
		parent->Nodes->Add(newNode1);
		Parse_Name(newNode1);

		// process terminal symbol ';' 
		currentUnit = CompilerData->Units->GetLexicUnit(this->CurrentLexicPosition);
		if( currentUnit.type == LUTypeSpecialCharacter  && currentUnit.subtype == SpecialCharacterSemicolon  )
		{
			SyntaxTreeNode * newNode2 = new SyntaxTreeNode();
			parent->Nodes->Add(newNode2);
			newNode2->LexUnitID=this->CurrentLexicPosition;
			newNode2->Production=Gr_Terminal;
			//increase counter
			CurrentLexicPosition++;
		}
		else
		{
			//report syntactic error
			CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_SEMICOLON_MATCH);
			//increase counter
			CurrentLexicPosition++;
		}

	}


	else
	{
		// ERROR has been found
		CompilerData->ErrorWarningReport->ReportError(&currentUnit, ERR_SYN_NO_GOTO_BLOCK_BEGINING);
		// MAKE LOGICAL RECOVERING
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("Parse_GotoBlock");
#endif
}